package org.dut.community.service;

import org.dut.community.entity.DiscussPost;
import org.dut.community.util.CommunityConstant;
import org.dut.community.util.RedisKeyUtil;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.dao.DataAccessException;
import org.springframework.data.redis.core.RedisOperations;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.SessionCallback;
import org.springframework.stereotype.Service;

import java.util.ArrayList;
import java.util.List;
import java.util.Set;

@Service
public class LikeService implements CommunityConstant {
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private DiscussPostService discussPostService;

    /**
     * 点赞
     * @param userId 点赞用户
     * @param entityType 实体类型(用户，帖子，评论)
     * @param entityId 实体id
     * @param entityUserId 实体用户id(用于显示用户获赞量)
     */
    public void like(int userId, int entityType, int entityId,int entityUserId) {
        redisTemplate.execute(new SessionCallback() {
            @Override
            public Object execute(RedisOperations operations) throws DataAccessException {
                String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
                String userLikeKey = RedisKeyUtil.getUserLikeKey(entityUserId);
                String postLikeKey = RedisKeyUtil.getLikePostKey(userId);
                // 查看是否点赞过
                boolean isLike = Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(entityLikeKey, userId));

                operations.multi();
                if (isLike) {
                    // 2. 取消点赞
                    operations.opsForSet().remove(entityLikeKey, userId);
                    operations.opsForValue().decrement(userLikeKey);
                    if(entityType == ENTITY_TYPE_POST) {
                        operations.opsForZSet().remove(postLikeKey, entityId);
                    }
                } else {
                    // 3. 点赞
                    operations.opsForSet().add(entityLikeKey, userId);
                    operations.opsForValue().increment(userLikeKey);
                    if(entityType == ENTITY_TYPE_POST) {
                        operations.opsForZSet().add(postLikeKey,entityId,System.currentTimeMillis());
                    }
                }
                operations.exec();
                return null;
            }
        });

    }

    /**
     * 某一实体的点赞数量
     * @param entityType 实体类型
     * @param entityId 实体id
     * @return 点赞数量
     */
    public long findEntityLikeCount(int entityType, int entityId) {
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        return redisTemplate.opsForSet().size(entityLikeKey) == null ? 0
                : redisTemplate.opsForSet().size(entityLikeKey);
    }

    /**
     * 判断某用户是否对某实体点赞
     * @param userId 点赞用户
     * @param entityType 实体类型
     * @param entityId 实体id
     * @return 点赞状态 1赞 0无
     */
    public int findEntityLikeStatus(int userId, int entityType, int entityId){
        String entityLikeKey = RedisKeyUtil.getEntityLikeKey(entityType, entityId);
        return Boolean.TRUE.equals(redisTemplate.opsForSet().isMember(entityLikeKey, userId)) ? 1 : 0;
    }

    /**
     * 查询用户收到赞的数量
     * @param userId 用户id
     * @return 点赞数量
     */
    public int findUserLikeCount(int userId){
        String userLikeKey = RedisKeyUtil.getUserLikeKey(userId);
        Integer count = (Integer) redisTemplate.opsForValue().get(userLikeKey);
        return count == null ? 0 : count;
    }

    /**
     * 查询一个用户点过赞的帖子
     * @param userId 用户id
     * @return 帖子列表
     */
    public List<DiscussPost> findUserLikePosts(int userId) {
        String redisKey = RedisKeyUtil.getLikePostKey(userId);

        // 获取存储在redis ZSet中的DiscussPost id，按score(点赞时间)降序排列
        Set<Integer> posts = redisTemplate.opsForZSet().reverseRange(redisKey, 0, -1);

        // 将结果转换为List
        List<DiscussPost> likePosts = new ArrayList<>();
        if (posts != null) {
            for(Integer postId : posts){
                DiscussPost post = discussPostService.findDiscussPostById(postId);
                if(post != null && post.getStatus() != 2) {
                    likePosts.add(post);
                }
            }
        }
        return likePosts;
    }



}
